<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<link rel="stylesheet" href="../style/journal.css" type="text/css" />
<style type="text/css"><!--
.googleadsense {
	margin: 2px;
	padding: 0px;
//--></style><script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-65008-1";
urchinTracker();
</script><title>DBIx::Class 的 inflate_column</title>
</head>
<body>
<a href="index.html">Journal</a>(2005) | <a href="../blog/"><b>Blog</b></a>(2006) | <a href="http://www.fayland.org/cgi-bin/random_link.pl">RandomLink</a> | <a href="AboutFayland.html">WhoAmI</a> | <a href="LiveBookmark.html">LiveBookmark</a> | <a href="http://www.fayland.org/">HomePage</a>
<p><&lt;Previous: <a href="Catalyst_Authentication.html">Catalyst 的用户鉴定登陆</a>&nbsp;&nbsp;>>Next: <a href="060224.html">another part-time job day</a></p>
<h1>DBIx::Class 的 inflate_column</h1>
<div class='content'>
<p>Category: <a href='Catalyst.html'>Catalyst</a> &nbsp; Keywords: <b>DBIx::Class inflate</b></p> <a href="http://search.cpan.org/perldoc?DBIx::Class">DBIx::Class</a> is great, 所以我在最近写的论坛代码 Foorum 中就使用了 DBIx::Class 作为我的 Model. (use base '<a href="http://dev.catalyst.perl.org">Catalyst</a>::Model::DBIC';)<br />但我挺喜欢 <a href="http://search.cpan.org/perldoc?Class::DBI">Class::DBI</a> 的 Trigger，而 DBIx::Class 要使用这个东西似乎比较麻烦。按它 <a href='http://dbix-class.shadowcatsystems.co.uk/index.cgi?UsageTips '>wiki</a> 上的说法似乎要载入 use base qw/ DBIx::Class::CDBICompat::Triggers DBIx::Class::Core/; 没有其他的办法。<p />我在写 Foorum 的注册程序，表 user 里有一个字段是 register_date 类型为 DATETIME。如果用 Trigger 的话似乎简单一些， register_date = NOW() 就可以（用 mysql 的函数）。<p />还好 DBIx::Class 也提供了 inflate. 所以我就用这个来完成我的任务。 inflate 在这里只是一个暗喻，它主要用于在表的某一字段的数据存入或取出之前做一些变动。 deflate 用于做存入前的变动，而 inflate 做取出后的变动。<p />在无法用 register_date = NOW() 之后，要将 localtime 或 gmtime 转为 DATATIME 类型似乎比较麻烦。还好 CPAN 上有一模块为 <a href="http://search.cpan.org/perldoc?DateTime::Format::MySQL">DateTime::Format::MySQL</a> 用于将 DateTime 对象转为 MySQL 所需要的类型。所以代码很简单：<br /><pre>package Foorum::Model::DBIC::User;<p />use strict;<br />use base 'Foorum::Model::DBIC';<p />use DateTime::Format::MySQL;<p />__PACKAGE__->inflate_column( 'register_date',<br />    { inflate => sub { return shift; },<br />      deflate => sub { DateTime::Format::MySQL->format_datetime( shift ); } }<br />);</pre>而当我们存入数据时就可以使用：<br /><pre>use DateTime;<br />$c->model('DBIC')->table('user')->create({ <br />    username  => $username,<br />    password  => $computed,<br />    email     => $email,<br />    register_date => DateTime->now,<br />    register_ip   => $c->req->address,<br />});</pre>当 create 创建新的 record 时，将传入的 register_date（这里是 DateTime->now;）先用 deflate 做一些变动，这里将它（shift 指的是 DateTime->now）处理（format_datetime）后再存入。<br />而 inflate 反一下，指取出后立即处理的匿名函数。我这里只是直接返回，因为我不需要再处理。如果你想它取出来也是一个 DateTime 对象好方便你进一步处理的话，可以将 inflate 的函数改为：<br /><pre>inflate => sub { DateTime::Format::MySQL->parse_datetime( shift ); },</pre>:) have fun. 如有疑问，发 mail 跟我探讨。 thanks.</div>
<p><&lt;Previous: <a href="Catalyst_Authentication.html">Catalyst 的用户鉴定登陆</a>&nbsp;&nbsp;>>Next: <a href="060224.html">another part-time job day</a></p>
<p><strong>Options:</strong> <a href='http://del.icio.us/post?title=DBIx::Class%20%E7%9A%84%20inflate_column&url=http://www.fayland.org/journal/DBIx_Class_inflate.html'>+Del.icio.us</a></p>

Created on <span class="digit">2006-02-23 23:42:15</span>, Last modified on <span class="digit">2006-02-23 23:44:15</span><br />
Copyright 2004-2006 All Rights Reserved. Powered by <a href="Eplanet.html">Eplanet</a> && <a href='http://catalyst.perl.org'>Catalyst</a> 5.65.
</body>
</html>